﻿using DataModel.Models;

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Security.Policy;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Media.Imaging;

namespace CommonLibrary.Helper
{
    public class PictureHelper
    {
        /// <summary>
        /// 转换图片为BMP格式，保存到壁纸目录下
        /// </summary>
        /// <param name="project"></param>
        public static void ConvertToBmp(ref Project project)
        {
            PictureBox pb = new PictureBox()
            {
                Image = Image.FromFile(project.Origin),
            };

            //1.导入图片
            //BitmapImage bitmap1 = ReadToBitmap(project.Origin);

            //2.获取图片输出路径
            project.Dir = DomainHelper.GetWallpaperPath(project.Dir);
            string oPath = Path.Combine(project.Dir, project.Path);
            string mPath = Path.Combine(project.Dir, project.Middle);
            string pPath = Path.Combine(project.Dir, project.Preview);

            //保存原图
            string oName = Path.GetFileName(project.Origin);
            string origin = Path.Combine(project.Dir, oName);    //原图
            File.Copy(project.Origin, origin, true);
            project.Origin = oName;

            //3.输出图片
            //SaveToBmp(bitmap1, oPath);

            //bitmap1.DecodePixelWidth = 960; // 设置解码宽度
            //bitmap1.DecodePixelHeight = 960; // 设置解码高度
            //SaveToBmp(bitmap1, mPath);

            //bitmap1.DecodePixelWidth = 200; // 设置解码宽度
            //bitmap1.DecodePixelHeight = 200; // 设置解码高度
            //SaveToBmp(bitmap1, pPath);

            pb.Image.Save(oPath, ImageFormat.Bmp);
            using (Bitmap bitmap = (Bitmap)pb.Image)
            {
                Size presize = new Size(960, 960 * bitmap.Height / bitmap.Width);
                using (Bitmap newBitmap = new Bitmap(bitmap, presize))
                {
                    newBitmap.Save(mPath, ImageFormat.Bmp);     //中等质量
                }

                Size icosize = new Size(200, 200 * bitmap.Height / bitmap.Width);
                using (Bitmap newBitmap = new Bitmap(bitmap, icosize))
                {
                    newBitmap.Save(pPath, ImageFormat.Bmp);     //预览图
                }
            }
        }

        /// <summary>
        /// 转换图片为bitmap
        /// </summary>
        /// <param name="path">图片路径</param>
        /// <param name="dpi"></param>
        /// <returns></returns>
        public static BitmapImage ConvertToBmp(string path, int dpi)
        {
            using FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 4096, useAsync: true);

            BitmapImage bitmap = new BitmapImage();
            bitmap.BeginInit();
            bitmap.CacheOption = BitmapCacheOption.OnLoad;
            bitmap.CreateOptions = BitmapCreateOptions.DelayCreation;
            bitmap.DecodePixelWidth = dpi; // 设置解码宽度
            bitmap.DecodePixelHeight = dpi; // 设置解码高度
            bitmap.StreamSource = stream;
            bitmap.EndInit();
            bitmap.Freeze();
            return bitmap;
        }

        public static BitmapImage ReadToBitmap(string path)
        {
            BitmapImage bitmap = new BitmapImage();
            bitmap.BeginInit();
            bitmap.UriSource = new Uri(path);
            bitmap.CacheOption = BitmapCacheOption.None;
            bitmap.CreateOptions = BitmapCreateOptions.DelayCreation;
            bitmap.EndInit();
            bitmap.Freeze();
            return bitmap;
        }

        public static Task<BitmapImage> LoadImageAsync(string path)
        {
            var tcs = new TaskCompletionSource<BitmapImage>();

            BitmapImage bitmap = new BitmapImage();
            bitmap.BeginInit();
            bitmap.UriSource = new Uri(path);
            bitmap.CacheOption = BitmapCacheOption.OnLoad;
            bitmap.CreateOptions = BitmapCreateOptions.None;

            bitmap.DownloadCompleted += (sender, e) =>
            {
                tcs.SetResult(bitmap); // 图像加载完成后设置结果
            };
            bitmap.DownloadFailed += (sender, e) =>
            {
                tcs.SetException(new Exception("下载图像失败")); // 如果加载失败则抛出异常
            };

            bitmap.EndInit();

            return tcs.Task;
        }

        public static Image LoadImageFromFile(string path)
        {
            return Image.FromFile(path);
        }

        public static void SaveToBmp(BitmapImage bitmap, string path)
        {
            var encoder = new BmpBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(bitmap));
            using FileStream fs = new FileStream(path, FileMode.OpenOrCreate);
            encoder.Save(fs);
        }

        /// <summary>
        /// 创建Bitmap对象
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static BitmapImage? CreateImage(string path, int? decodeWidth = null, int? decodeHeight = null)
        {
            if (!File.Exists(path))
            {
                return null;
            }

            try
            {
                var bitmap = new BitmapImage();
                bitmap.BeginInit();
                bitmap.UriSource = new Uri(path, UriKind.RelativeOrAbsolute);
                bitmap.CacheOption = BitmapCacheOption.OnLoad; // 确保流关闭后可用

                if (decodeWidth.HasValue)
                {
                    bitmap.DecodePixelWidth = decodeWidth.Value;
                }
                if (decodeHeight.HasValue)
                {
                    bitmap.DecodePixelHeight = decodeHeight.Value;
                }

                bitmap.EndInit();
                bitmap.Freeze(); // 跨线程安全操作
                return bitmap;
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 创建Bitmap对象
        /// </summary>
        /// <param name="path"></param>
        /// <param name="dpi"></param>
        /// <returns></returns>
        public static BitmapImage? CreateImage(string path, int dpi)
        {
            return CreateImage(path, dpi, null);
        }

        public static void ExportToBmp(string path, int dpi, string outPath)
        {
            var bmp = CreateImage(path, dpi);
            if (bmp != null)
            {
                SaveToBmp(bmp, outPath);
            }
        }
    }
}
